(function ($) {
    /**
     * 扩展dateli时间格式化
     */
    Date.prototype.format = function (fmt) {
        var o = {
            "M+": this.getMonth() + 1,                 //月份
            "d+": this.getDate(),                    //日
            "h+": this.getHours(),                   //小时
            "m+": this.getMinutes(),                 //分
            "s+": this.getSeconds(),                 //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds()             //毫秒
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        }
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
        }
        return fmt;
    };
    /**
     * jquery扩展控件-时间轴
     * @author lzugis
     * @create-time 2017/11/28
     * @param options
     * @returns {jQuery}
     */
    $.fn.TimeLine = function (options) {
        var scope = this;
        var defaults = {
            callback:function(date){console.log(date)},
            autoplay:false,
            interval:1000
        };

        scope.dates = [];
        scope.selectedDate = null;
        window.playflag = 0;

        var hour_count=0,
            line_width=0,
            played, currtime,
            ghost_timecode, ghost_time,
            main_timecode, main_time, loader_path,
            playpause,
            calendar, calendar_width;
        /**
         * 初始化函数
         * @private
         */
        scope._init = function() {
            //将default和options合并
            scope.options = $.extend({}, defaults, options);
            scope.addClass("progress-bar");

            var progress_line = $("<div/>").addClass("progress-line");
            played = $("<div/>").addClass("played");
            var avbl = $("<div/>").addClass("avbl");
            currtime = $("<i/>").addClass("curr-time");
            progress_line.append(played).append(avbl).append(currtime);

            ghost_timecode = $("<div/>").addClass("timecode").addClass("ghost-timecode");
            ghost_time = $("<div/>").addClass("box");
            ghost_timecode.append(ghost_time);

            main_timecode = $("<div/>").addClass("timecode").addClass("main-timecode");
            main_time = $("<div/>").addClass("box");
            loader_path = $("<img class='loader loader-path' width='19' height='8'>");
            main_timecode.append(main_time).append(loader_path);

            playpause = $("<div/>").addClass("playpause").attr("isplay", scope.options.autoplay);

            calendar = $("<div/>").addClass("calendar");

            scope.append(progress_line).append(ghost_timecode).append(main_timecode)
                .append(playpause).append(calendar);

            var date_len = 0;
            for(var date in options.times){
                var times = options.times[date];
                hour_count+=times.length;

                date_len++;

                date = scope._formatDate(date, date.length);
                scope.dates.push(date);
                var _date = new Date(date);
                var click_able = $("<div/>").addClass("clickable").html(scope._getDateStr(_date));
                click_able.attr("date", date);
                calendar.append(click_able);
                //点击事件
                click_able.on("click", function(){
                    var selected_date = $(this).attr("date");
                    selected_date = new Date(selected_date+" 12:00").getTime();
                    scope.selectByDate(selected_date);
                });
            }
            $(".clickable").css("width", "calc( "+(100/date_len)+"% - 1px )");
            line_width = avbl.width();
            calendar_width = calendar.width();

            //设置初始化状态
            scope.selectByDate(new Date().getTime());
            //设置当前时间, 并设置整点触发
            scope._setCurrentTime();
            setInterval(function(){
                var curr_min = new Date().format("mm");
                if(curr_min==="00")scope._setCurrentTime();
            }, 5*60*1000);

            //自动播放
            if(scope.options.autoplay)scope._play();

            /**
             * 事件
             */
            progress_line.on("mousemove", function(e){
                //判断两个div是否叠加
                var ghost_left = ghost_timecode.position().left,
                    ghost_right = ghost_left+ghost_timecode.width(),
                    main_left = main_timecode.position().left,
                    main_right = main_left+main_timecode.width();
                var isIn = false;
                if(ghost_right>main_left&&ghost_left<main_left){
                    isIn = true;
                }else if(ghost_right>main_right&&ghost_left<main_right){
                    isIn = true;
                }else if(ghost_left>main_left&&ghost_right<main_right){
                    isIn = true;
                }else{
                    isIn = false;
                }
                var offsetX = e.offsetX;
                ghost_timecode.css({
                    "left":(offsetX + 45)+"px",
                    "opacity":1,
                    "top":isIn? "-3.5rem" : "-1.8rem"
                });
                var hover_date = scope._getDateByOffset(offsetX);
                ghost_time.html(new Date(hover_date).format("hh:")+"00");
            });
            progress_line.on("mouseout", function(){
                ghost_timecode.css({
                    "opacity":0
                });
            });
            progress_line.on("click", function(e){
                var offsetX = e.offsetX;
                var click_date = scope._getDateByOffset(offsetX);
                scope.selectByDate(click_date);
            });

            playpause.on("click", function(){
                var isplay = $(this).attr("isplay");
                if(isplay==="true"){
                    $(this).removeClass("pause").attr("isplay", false);
                    scope._pause();
                }else{
                    $(this).addClass("pause").attr("isplay", true);
                    scope._play();
                }
            });
        };
        /**
         * 播放
         * @private
         */
        scope._play = function(){
            window.playflag = setInterval(function(){
                var last2Date = scope.dates[scope.dates.length-1]+" 23:00";
                if(scope.selectedDate.format("yyyy-MM-dd hh:00")===last2Date)
                    scope.selectedDate = new Date(scope.dates[0]+" 00:00");
                scope.selectByDate(scope.selectedDate.getTime()+60*60*1000);
            },scope.options.interval)
        };
        /**
         * 暂停播放
         * @private
         */
        scope._pause = function(){
          window.clearInterval(window.playflag);
        };
        /**
         * 根据时间获取偏移量
         * @param offset
         * @returns {number}
         * @private
         */
        scope._getDateByOffset = function(offset){
            var perOff = offset/line_width*hour_count;
            var start_date = new Date(scope.dates[0]+" 00:00").getTime();
            return start_date+perOff*60*60*1000;
        };
        /**
         * 更新当前时间
         * @private
         */
        scope._setCurrentTime = function(){
            var currDate = new Date().getTime();
            var offsetX = scope._getDateOffset(currDate);
            currtime.css("left", offsetX + "px");
        };
        /**
         * 根据时间选择，单位是ms
         * @param date
         */
        scope.selectByDate = function(date){
            var offsetX = scope._getDateOffset(date);
            main_timecode.css("left", (offsetX + 45) + "px");
            played.css("width", offsetX + "px");
            date = new Date(date);
            main_time.html(scope._getDateStr(date)+" - "+date.format("hh")+":00");
            if(scope.options.callback)scope.options.callback.apply(this, arguments);
            scope.selectedDate = date;
        };
        /**
         * 获取时间偏移量
         * @param date
         * @returns {number}
         * @private
         */
        scope._getDateOffset = function(date){
            var start_date = new Date(scope.dates[0]+" 00:00").getTime(),
                end_date = new Date(scope.dates[scope.dates.length-1]+" 23:00").getTime();
            var perX = (date-start_date)/(end_date-start_date),
                offsetX = perX*line_width;
            return offsetX;
        };
        /**
         * 时间格式化
         * @param date
         * @returns {string}
         * @private
         */
        scope._getDateStr = function (date) {
            var weekMap = {"1":"周一", "2":"周二", "3":"周三", "4":"周四", "5":"周五", "6":"周六", "0":"周日"};
            return weekMap[date.getDay()]+" "+date.format("dd");
        };
        /**
         * 时间转换函数
         * @param strDate
         * @param len
         * @returns {string}
         * @private
         */
        scope._formatDate = function (strDate, len){
            switch (len){
                case 4:{//yyyy
                    return strDate.substr(0,4);
                    break;
                }
                case 6:{//yyyy-MM
                    return strDate.substr(0,4)+"-"+strDate.substr(4,2);
                    break;
                }
                case 8:{//yyyy-MM-dd
                    return strDate.substr(0,4)+"-"+strDate.substr(4,2)
                        +"-"+strDate.substr(6,2);
                    break;
                }
                case 10:{//yyyy-MM-dd hh
                    return strDate.substr(0,4)+"-"+strDate.substr(4,2)
                        +"-"+strDate.substr(6,2)+" "+strDate.substr(8,2);
                    break;
                }
                case 12:{//yyyy-MM-dd hh:mm
                    return strDate.substr(0,4)+"-"+strDate.substr(4,2)
                        +"-"+strDate.substr(6,2)+" "+strDate.substr(8,2)+":"+strDate.substr(10,2);
                    break;
                }
                default:{//yyyy-MM-dd hh:mm:ss
                    return strDate.substr(0,4)+"-"+strDate.substr(4,2)
                        +"-"+strDate.substr(6,2)+" "+strDate.substr(8,2)
                        +":"+strDate.substr(10,2)+":"+strDate.substr(12,2);
                    break;
                }
            }

        };

        //自动执行初始化函数
        scope._init();

        //返回函数对象
        return this;
    };
})(jQuery);